/**
 * User: Obi
 * Date: 31.07.11
 * Time: 16:33
 */
package com.jediflasher.game_client.server {
	import com.jediflasher.game_client.server.messages.ChangeUsers;
	import com.jediflasher.game_client.server.messages.CharacterInfoResponse;
	import com.jediflasher.game_client.server.messages.Header;
	import com.jediflasher.game_client.server.messages.LoginResponse;
	import com.jediflasher.game_client.server.messages.MethodLogin;
	import com.jediflasher.game_client.server.messages.MethodMovement;
	import com.jediflasher.game_client.server.messages.ServiceType;
	import com.jediflasher.game_client.server.messages.WorldInfoResponse;
	import com.netease.protobuf.Message;

	import flash.utils.IDataInput;

	public class MessageWrapper {

		public function MessageWrapper() {
			super();
		}

		/**
		 * Id серверного сервиса, например LOGIN
		 */
		public var serviceType:int;

		/**
		 * Уникальный Id запроса. По нему можно определить, на какое конкретно сообщение ответил сервер
		 */
		public var requestId:int;

		/**
		 * Тип сообщения, например MessageWrapper.MESSAGE_TYPE_ERROR
		 */
		public var messageType:int;

		/**
		 * Тип сообщения от конкретного сервиса
		 */
		public var method:int;

		/**
		 * Тело сообщения, десериализованный brotobuf
		 */
		public var message:Message;


		private var _header:Header;
		/**
		 * Считывает основные данные сообщения, для считывания конкретного сообщения, нужно вызвать метод readMessage
		 */
		public function read(input:IDataInput):MessageWrapper {
			var headerSize:int = input.readInt();
			_header = new Header();

			_header.readFromSlice(input, input.bytesAvailable - headerSize);

			this.serviceType = _header.serviceType;
			this.messageType = _header.messageType;
			this.requestId = _header.requestId;
			this.method = _header.method;

			// может прийти башка без тела
			if (_header.bodySize == 0) return this;

			switch (_header.serviceType) {
				case ServiceType.LOGIN:
					message = readAsLoginMessage();
					break;
				case ServiceType.MOVEMENT:
					message = readAsMovementMessage();
					break;
			}

			if (message) message.readFromSlice(input, input.bytesAvailable - _header.bodySize);

			return this;
		}

		private function readAsLoginMessage():Message {
			switch (this.method) {
				case MethodLogin.LOGIN:
					return new LoginResponse();
			}
			return null;
		}

		private function readAsMovementMessage():Message {
			switch (this.method) {
				case MethodMovement.CHARACTER_MOVE:
				case MethodMovement.CHARACTER_INFO:
					return new CharacterInfoResponse();
				case MethodMovement.WORLD_INFO:
					return new WorldInfoResponse();
				case MethodMovement.USERS_ADD:
				case MethodMovement.USERS_REMOVE:
					return new ChangeUsers();
			}
			return null;
		}


		public function toString():String {
			return "header >\n"+ _header+"\nmessage >\n"+message;
		}
	}
}
